* optimize speed and distance conversions.
structure constexpr conversions such that a minimal amount of
arithmetic is done at run time and avoiding run time division.
add tests for conversions.
* correct bug with display of accumulated path distance.
and add test case of same.
constexpr double kMilesPerMeter = 1.0 / kMetersPerMile;
constexpr double kKilometersPerMile = 1.609344; /* exact in decimal notation */
constexpr double kMilesPerKilometer = 1.0 / kKilometersPerMile;
+constexpr double kMetersPerNMile = 1852.0; /* exact in decimal notation */
+constexpr double kNMilesPerMeter = 1.0 / kMetersPerNMile;
-constexpr double FEET_TO_METERS(double feetsies) { return (feetsies) * kMetersPerFoot; }
-constexpr double METERS_TO_FEET(double meetsies) { return (meetsies) * kFeetPerMeter; }
+constexpr double FEET_TO_METERS(double feetsies) { return feetsies * kMetersPerFoot;}
+constexpr double METERS_TO_FEET(double meetsies) { return meetsies * kFeetPerMeter;}
-constexpr double NMILES_TO_METERS(double a) { return a * 1852.0;} /* nautical miles */
-constexpr double METERS_TO_NMILES(double a) { return a / 1852.0;}
+constexpr double NMILES_TO_METERS(double a) { return a * kMetersPerNMile;} /* nautical miles */
+constexpr double METERS_TO_NMILES(double a) { return a * kNMilesPerMeter;}
-constexpr double MILES_TO_METERS(double a) { return (a) * kMetersPerMile;}
-constexpr double METERS_TO_MILES(double a) { return (a) * kMilesPerMeter;}
-constexpr double FATHOMS_TO_METERS(double a) { return (a) * 1.8288;}
+constexpr double MILES_TO_METERS(double a) { return a * kMetersPerMile;}
+constexpr double METERS_TO_MILES(double a) { return a * kMilesPerMeter;}
+constexpr double FATHOMS_TO_METERS(double a) { return a * 1.8288;}
-constexpr double CELSIUS_TO_FAHRENHEIT(double a) { return (((a) * 1.8) + 32.0);}
-constexpr double FAHRENHEIT_TO_CELSIUS(double a) { return (((a) - 32.0) / 1.8);}
+constexpr double CELSIUS_TO_FAHRENHEIT(double a) { return (a * 1.8) + 32.0;}
+constexpr double FAHRENHEIT_TO_CELSIUS(double a) { return (a - 32.0) / 1.8;}
constexpr long SECONDS_PER_HOUR = 60L * 60;
constexpr long SECONDS_PER_DAY = 24L * 60 * 60;
+constexpr double kKPHPerMPS = SECONDS_PER_HOUR / 1000.0;
+constexpr double kMPSPerKPH = 1.0 / kKPHPerMPS;
+constexpr double kMPHPerMPS = kMilesPerMeter * SECONDS_PER_HOUR;
+constexpr double kMPSPerMPH = 1.0 / kMPHPerMPS;
+constexpr double kKnotsPerMPS = kNMilesPerMeter * SECONDS_PER_HOUR;
+constexpr double kMPSPerKnot = 1.0 / kKnotsPerMPS;
+
/* meters/second to kilometers/hour */
-constexpr double MPS_TO_KPH(double a) { return (a)*SECONDS_PER_HOUR/1000.0;}
+constexpr double MPS_TO_KPH(double a) { return a * kKPHPerMPS;}
/* meters/second to miles/hour */
-constexpr double MPS_TO_MPH(double a) { return METERS_TO_MILES(a) * SECONDS_PER_HOUR;}
+constexpr double MPS_TO_MPH(double a) { return a * kMPHPerMPS;}
-/* meters/second to knots */
-constexpr double MPS_TO_KNOTS(double a) { return MPS_TO_KPH((a)/1.852);}
+/* meters/second to knots(nautical miles/hour) */
+constexpr double MPS_TO_KNOTS(double a) { return a * kKnotsPerMPS;}
/* kilometers/hour to meters/second */
-constexpr double KPH_TO_MPS(double a) { return a * 1000.0/SECONDS_PER_HOUR;}
+constexpr double KPH_TO_MPS(double a) { return a * kMPSPerKPH;}
/* miles/hour to meters/second */
-#define MPH_TO_MPS(a) (MILES_TO_METERS(a) / SECONDS_PER_HOUR)
+constexpr double MPH_TO_MPS(double a) { return a * kMPSPerMPH;}
-/* knots to meters/second */
-constexpr double KNOTS_TO_MPS(double a) {return KPH_TO_MPS(a) * 1.852; }
+/* knots(nautical miles/hour) to meters/second */
+constexpr double KNOTS_TO_MPS(double a) {return a * kMPSPerKnot;}
#define MILLI_TO_MICRO(t) ((t) * 1000) /* Milliseconds to Microseconds */
#define MICRO_TO_MILLI(t) ((t) / 1000) /* Microseconds to Milliseconds*/
unsigned char cadence; /* revolutions per minute */
float power; /* watts, as measured by cyclists */
float temperature; /* Degrees celsius */
- float odometer_distance; /* Meters? */
+ float odometer_distance; /* Meters */
geocache_data* gc_data;
FormatSpecificDataList fs;
const session_t* session; /* pointer to a session struct */
--- /dev/null
+lat,lon,alt
+40.0,-105.0,1.0m
+40.0,-105.0,1.0ft
+40.0,-105.0,1.0km
+40.0,-105.0,1.0nm
+40.0,-105.0,1.0mi
+40.0,-105.0,1.0fa
--- /dev/null
+Lat,Lon,Dist(m)
+40.000000,-105.000000,1.0
--- /dev/null
+Lat,Lon,Dist(m),Dist(mile),Dist(nautical miles)
+40.000000,-105.000000,1.000000e+00,6.213712e-04,5.399568e-04
--- /dev/null
+UTM
+21N 499500 0
+21N 500500 0
--- /dev/null
+Utm,Dist(m),Dist(km),Dist(mile),Dist(nautical miles)
+21N 499500 0,0.000000e+00,0.000000e+00,0.000000e+00,0.000000e+00
+21N 500500 0,1.000400e+03,1.000400e+00,6.216198e-01,5.401729e-01
--- /dev/null
+Lat,Lon,Alt(m),Alt(ft)
+40.000000,-105.000000,1.000000e+00,3.280840e+00
+40.000000,-105.000000,3.048000e-01,1.000000e+00
+40.000000,-105.000000,1.000000e+03,3.280840e+03
+40.000000,-105.000000,1.852000e+03,6.076115e+03
+40.000000,-105.000000,1.609344e+03,5.280000e+03
+40.000000,-105.000000,1.828800e+00,6.000000e+00
--- /dev/null
+lat,lon,speed
+40.0,-105.0,1.0mps
+40.0,-105.0,1.0kmh
+40.0,-105.0,1.0mph
+40.0,-105.0,1.0knot
+
--- /dev/null
+Lat,Lon,Speed(m/s),Speed(km/hr),Speed(mile/hr),Speed(knots)
+40.000000,-105.000000,1.000000e+00,3.600000e+00,2.236936e+00,1.943844e+00
+40.000000,-105.000000,2.777778e-01,1.000000e+00,6.213712e-01,5.399568e-01
+40.000000,-105.000000,4.470400e-01,1.609344e+00,1.000000e+00,8.689762e-01
+40.000000,-105.000000,5.144445e-01,1.852000e+00,1.150780e+00,1.000000e+00
--- /dev/null
+# This covers conversions to and from various speed units.
+echo 'DESCRIPTION Speed Test' > speed.style
+echo 'EXTENSION csv' >> speed.style
+echo 'FIELD_DELIMITER COMMA' >> speed.style
+echo 'RECORD_DELIMITER NEWLINE' >> speed.style
+echo 'DATATYPE TRACK' >> speed.style
+echo 'PROLOGUE Lat,Lon,Speed(m/s),Speed(km/hr),Speed(mile/hr),Speed(knots)' >> speed.style
+echo 'OFIELD LAT_DECIMAL,"","%f"' >> speed.style
+echo 'OFIELD LON_DECIMAL,"","%f"' >> speed.style
+echo 'OFIELD PATH_SPEED,"","%.6e"' >> speed.style
+echo 'OFIELD PATH_SPEED_KPH,"","%.6e"' >> speed.style
+echo 'OFIELD PATH_SPEED_MPH,"","%.6e"' >> speed.style
+echo 'OFIELD PATH_SPEED_KNOTS,"","%.6e"' >> speed.style
+
+gpsbabel -t -i unicsv -f ${REFERENCE}/speed.csv -o xcsv,style=speed.style -F ${TMPDIR}/speed~csv.csv
+compare ${REFERENCE}/speed~csv.csv ${TMPDIR}/speed~csv.csv
+
+# This covers distance conversions to meters, but only a couple from meters.
+echo 'DESCRIPTION Distance Test' > distance.style
+echo 'EXTENSION csv' >> distance.style
+echo 'FIELD_DELIMITER COMMA' >> distance.style
+echo 'RECORD_DELIMITER NEWLINE' >> distance.style
+echo 'DATATYPE TRACK' >> distance.style
+echo 'PROLOGUE Lat,Lon,Alt(m),Alt(ft)' >> distance.style
+echo 'OFIELD LAT_DECIMAL,"","%f"' >> distance.style
+echo 'OFIELD LON_DECIMAL,"","%f"' >> distance.style
+echo 'OFIELD ALT_METERS,"","%.6e"' >> distance.style
+echo 'OFIELD ALT_FEET,"","%.6e"' >> distance.style
+
+gpsbabel -t -i unicsv -f ${REFERENCE}/distance.csv -o xcsv,style=distance.style -F ${TMPDIR}/distance~csv.csv
+compare ${REFERENCE}/distance~csv.csv ${TMPDIR}/distance~csv.csv
+
+# This covers additional distance conversions from meters.
+echo 'DESCRIPTION Distance 2 Test' > distance2.style
+echo 'EXTENSION csv' >> distance2.style
+echo 'FIELD_DELIMITER COMMA' >> distance2.style
+echo 'RECORD_DELIMITER NEWLINE' >> distance2.style
+echo 'DATATYPE TRACK' >> distance2.style
+echo 'PROLOGUE Lat,Lon,Dist(m),Dist(mile),Dist(nautical miles)' >> distance2.style
+echo 'IFIELD LAT_DECIMAL,"","%f"' >> distance2.style
+echo 'IFIELD LON_DECIMAL,"","%f"' >> distance2.style
+echo 'IFIELD PATH_DISTANCE_METERS,"","%.6e"' >> distance2.style
+echo 'OFIELD LAT_DECIMAL,"","%f"' >> distance2.style
+echo 'OFIELD LON_DECIMAL,"","%f"' >> distance2.style
+echo 'OFIELD PATH_DISTANCE_METERS,"","%.6e"' >> distance2.style
+echo 'OFIELD PATH_DISTANCE_MILES,"","%.6e"' >> distance2.style
+echo 'OFIELD PATH_DISTANCE_NAUTICAL_MILES,"","%.6e"' >> distance2.style
+
+gpsbabel -t -i xcsv,style=distance2.style -f ${REFERENCE}/distance2.csv -o xcsv,style=distance2.style -F ${TMPDIR}/distance2~csv.csv
+compare ${REFERENCE}/distance2~csv.csv ${TMPDIR}/distance2~csv.csv
+
+# This covers xcsv path distances.
+# Reference has points ~1000m apart.
+echo 'DESCRIPTION Distance 3 Test' > distance3.style
+echo 'EXTENSION csv' >> distance3.style
+echo 'FIELD_DELIMITER COMMA' >> distance3.style
+echo 'RECORD_DELIMITER NEWLINE' >> distance3.style
+echo 'DATATYPE TRACK' >> distance3.style
+echo 'PROLOGUE Utm,Dist(m),Dist(km),Dist(mile),Dist(nautical miles)' >> distance3.style
+echo 'IFIELD UTM,"","%s"' >> distance3.style
+echo 'OFIELD UTM,"","%s"' >> distance3.style
+echo 'OFIELD PATH_DISTANCE_METERS,"","%.6e"' >> distance3.style
+echo 'OFIELD PATH_DISTANCE_KM,"","%.6e"' >> distance3.style
+echo 'OFIELD PATH_DISTANCE_MILES,"","%.6e"' >> distance3.style
+echo 'OFIELD PATH_DISTANCE_NAUTICAL_MILES,"","%.6e"' >> distance3.style
+
+gpsbabel -t -i xcsv,style=distance3.style -f ${REFERENCE}/distance3.csv -o xcsv,style=distance3.style -F ${TMPDIR}/distance3~csv.csv
+compare ${REFERENCE}/distance3~csv.csv ${TMPDIR}/distance3~csv.csv
#include "formspec.h" // for FormatSpecificDataList
#include "garmin_fs.h" // for garmin_fs_t, garmin_fs_alloc
#include "gbfile.h" // for gbfgetstr, gbfclose, gbfopen, gbfile
-#include "grtcirc.h" // for RAD, gcdist, radtomiles
+#include "grtcirc.h" // for RAD, gcdist, radtometers
#include "jeeps/gpsmath.h" // for GPS_Math_WGS84_To_UTM_EN, GPS_Lookup_Datum_Index, GPS_Math_Known_Datum_To_WGS84_M, GPS_Math_UTM_EN_To_Known_Datum, GPS_Math_WGS84_To_Known_Datum_M, GPS_Math_WGS84_To_UKOSMap_M
#include "jeeps/gpsport.h" // for int32
#include "session.h" // for session_t
{ "PATH_DISTANCE_KM", XT_PATH_DISTANCE_KM },
{ "PATH_DISTANCE_METERS", XT_PATH_DISTANCE_METERS },
{ "PATH_DISTANCE_MILES", XT_PATH_DISTANCE_MILES },
+ { "PATH_DISTANCE_NAUTICAL_MILES", XT_PATH_DISTANCE_NAUTICAL_MILES },
{ "PATH_SPEED", XT_PATH_SPEED },
{ "PATH_SPEED_KNOTS", XT_PATH_SPEED_KNOTS },
{ "PATH_SPEED_KPH", XT_PATH_SPEED_KPH },
case XcsvStyle::XT_PATH_DISTANCE_MILES:
wpt->odometer_distance = MILES_TO_METERS(atof(s));
break;
+ case XcsvStyle::XT_PATH_DISTANCE_NAUTICAL_MILES:
+ wpt->odometer_distance = NMILES_TO_METERS(atof(s));
+ break;
case XcsvStyle::XT_HEART_RATE:
wpt->heartrate = atoi(s);
break;
char utmzc;
if (oldlon < 900) {
- pathdist += radtomiles(gcdist(RAD(oldlat),RAD(oldlon),
- RAD(wpt->latitude),RAD(wpt->longitude)));
+ pathdist += radtometers(gcdist(RAD(oldlat),RAD(oldlon),
+ RAD(wpt->latitude),RAD(wpt->longitude)));
}
longitude = oldlon = wpt->longitude;
latitude = oldlat = wpt->latitude;
if (wpt->odometer_distance) {
buff = QString::asprintf(fmp.printfc.constData(), METERS_TO_MILES(wpt->odometer_distance));
} else {
- buff = QString::asprintf(fmp.printfc.constData(), pathdist);
+ buff = QString::asprintf(fmp.printfc.constData(), METERS_TO_MILES(pathdist));
+ }
+ break;
+ case XcsvStyle::XT_PATH_DISTANCE_NAUTICAL_MILES:
+ /* path (route/track) distance in miles */
+ if (wpt->odometer_distance) {
+ buff = QString::asprintf(fmp.printfc.constData(), METERS_TO_NMILES(wpt->odometer_distance));
+ } else {
+ buff = QString::asprintf(fmp.printfc.constData(), METERS_TO_NMILES(pathdist));
}
break;
case XcsvStyle::XT_PATH_DISTANCE_METERS:
if (wpt->odometer_distance) {
buff = QString::asprintf(fmp.printfc.constData(), wpt->odometer_distance);
} else {
- buff = QString::asprintf(fmp.printfc.constData(), MILES_TO_METERS(pathdist));
+ buff = QString::asprintf(fmp.printfc.constData(), pathdist);
}
break;
case XcsvStyle::XT_PATH_DISTANCE_KM:
if (wpt->odometer_distance) {
buff = QString::asprintf(fmp.printfc.constData(), wpt->odometer_distance / 1000.0);
} else {
- buff = QString::asprintf(fmp.printfc.constData(), MILES_TO_METERS(pathdist) / 1000.0);
+ buff = QString::asprintf(fmp.printfc.constData(), pathdist / 1000.0);
}
break;
case XcsvStyle::XT_PATH_SPEED:
XT_PATH_DISTANCE_KM,
XT_PATH_DISTANCE_METERS,
XT_PATH_DISTANCE_MILES,
+ XT_PATH_DISTANCE_NAUTICAL_MILES,
XT_PATH_SPEED,
XT_PATH_SPEED_KNOTS,
XT_PATH_SPEED_KPH,
</para>
<screen format="linespecific">PATH_DISTANCE_MILES,"","%f"
</screen>
+ </section>
+ <section id="style_def_pathdistnm">
+ <title>PATH_DISTANCE_NAUTICAL_MILES</title>
+ <para>PATH_DISTANCE_NAUTICAL_MILES is like PATH_DISTANCE_MILES except it outputs the
+ length in nautical miles.
+</para>
</section>
<section id="style_def_pathdistkm">
<title>PATH_DISTANCE_KM</title>